﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BoYuanCore.Framework.Extensions;
using KeXin.Model.Output;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Serilog;

namespace KeXinApi.Code.Attributes
{
    /// <summary>
    /// 输入模型验证
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
    public class ValidateInputAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            if (!context.ModelState.IsValid)
            {
                // 捕获请求 JSON
                var stream = context.HttpContext.Request.Body;
                context.HttpContext.Request.EnableBuffering();
                if (stream.CanSeek)
                    stream.Seek(0, SeekOrigin.Begin);
                string jsonStr = new StreamReader(stream, Encoding.UTF8).ReadToEnd();
                var url = context.HttpContext.Request.GetEncodedUrl();

                StringBuilder sb2 = new StringBuilder();
                sb2.AppendLine("========请求json开始========");
                sb2.AppendLine("url: " + url);
                sb2.AppendLine(jsonStr);
                sb2.AppendLine("========请求json结束========");
                string jsonError = sb2.ToString();

                try
                {
                    string num = Guid.NewGuid().ToString("N");
                    string timeStr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("");
                    sb.AppendLine(" => ValidateInputAttribute 异常");
                    sb.AppendLine("****************************异常开始:" + timeStr + "****************************");
                    sb.AppendLine("异常编号:" + num);
                    sb.AppendLine("【异常类型】：ValidateInputAttribute 验证错误 => " + context.ActionDescriptor.DisplayName);
                    sb.AppendLine("【异常信息】：" + context.ModelState.Values.First().Errors[0].ErrorMessage);
                    sb.AppendLine(jsonError);
                    sb.AppendLine("****************************异常结束:" + timeStr + "****************************");

                    Log.Error(sb.ToString());
                    //throw new Exception(sb.ToString());
                    context.Result = new JsonResult(ResponseOutput.NotOk("异常编号:" + num + " => " + context.ModelState.Values.First().Errors[0].ErrorMessage, 500));
                }
                catch (Exception e)
                {
                    context.Result = new StatusCodeResult(StatusCodes.Status500InternalServerError);
                    string num = Guid.NewGuid().ToString("N");
                    Log.Error(e.GetBaseException().GetExceptionMsg("异常编号(ValidateInputAttribute):" + num + jsonError));
                }

            }
        }
    }
}
